/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package irsystem.collection;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Cerulean
 */
public class CISI implements Serializable
{
    List<CISIDocs> docs;
    List<CISIQRels> rels;
    List<CISIQuery> queries;
    List<CISIStopword> stopwords;
    private final static int STATE_START=0;
    private final static int PARSING_INDEX=1;
    private final static int PARSING_WORDS=2;
    private final static int PARSING_AUTHOR=3;
    private final static int PARSING_PUBLISH=4;
    private final static int PARSING_QUERY=5;
    private final static int PARSING_X=6;
    private final static int PARSING_TITLE=7;
    private final static int STATE_END=8;
    
    public static CISI readFromFiles(String docfile,String relfile, String queryfile, String stopfile) throws FileNotFoundException, IOException
    {
        CISI cisi=new CISI();
        cisi.docs=readDocFile(docfile);
        cisi.rels=readRelations(relfile);
        cisi.queries=readQueries(queryfile);
        cisi.stopwords=readStopwords(stopfile);
        return cisi;
    }

    private static List<CISIQuery> readQueries(String queryfile) throws FileNotFoundException, IOException
    {
        List<CISIQuery> queries=new ArrayList<CISIQuery>();
        FileReader fr=new FileReader(queryfile);
        BufferedReader br=new BufferedReader(fr);
        String line;
        int index=-1;
        String words="";
        CISIQuery query;
        int state=STATE_START;
        String title="";
        String author="";
        String publish="";
        String newline=System.getProperty("line.separator");
        while(br.ready())
        {
            line=br.readLine();
            if(line.length()>1)
            {
                if(line.substring(0, 2).equals(".I"))
                {
                    if(state!=STATE_START)
                    {
                        // add entry
                        query=new CISIQuery(index, title, words, author, publish);
                        queries.add(query);
                    }
                    state=PARSING_INDEX;
                    title="";
                    author="";
                    words="";
                    publish="";
                }
                else if(line.substring(0, 2).equals(".W"))
                {
                    state=PARSING_WORDS;
                    line=br.readLine();
                }
                else if(line.substring(0, 2).equals(".T"))
                {
                    state=PARSING_TITLE;
                    line=br.readLine();
                }
                else if(line.substring(0, 2).equals(".A"))
                {
                    state=PARSING_AUTHOR;
                    line=br.readLine();
                }
            }
            switch(state)
            {
                case PARSING_INDEX:
                    index=Integer.parseInt(line.substring(3),10);
                    break;
                case PARSING_TITLE:
                    title+=line+newline;
                    break;
                case PARSING_AUTHOR:
                    author+=line+newline;
                    break;
                case PARSING_WORDS:
                    words+=line+newline;
                    break;
                case PARSING_PUBLISH:
                    publish+=line+newline;
                    break;
            }
        }
        query=new CISIQuery(index, title, words, author, publish);
        queries.add(query);
        return queries;
    }
    
    private static List<CISIStopword> readStopwords(String stopfile) throws FileNotFoundException, IOException
    {
        List<CISIStopword> stops=new ArrayList<CISIStopword>();
        FileReader fr=new FileReader(stopfile);
        BufferedReader br=new BufferedReader(fr);
        CISIStopword stopword;
        while(br.ready())
        {
            stopword=new CISIStopword(br.readLine());
            stops.add(stopword);
        }
        return stops;
    }
    
    private static List<CISIQRels> readRelations(String relfile) throws FileNotFoundException, IOException
    {
        List<CISIQRels> rels=new ArrayList<CISIQRels>();
        FileReader fr=new FileReader(relfile);
        BufferedReader br=new BufferedReader(fr);
        CISIQRels rel;
        String line;
        while(br.ready())
        {
            line=br.readLine();
            String[] arrays=line.split(" ");
            rel=new CISIQRels(Integer.parseInt(arrays[0],10), Integer.parseInt(arrays[1],10), Integer.parseInt(arrays[2],10), Integer.parseInt(arrays[3],10));
            rels.add(rel);
        }
        return rels;
    }
    
    private static List<CISIDocs> readDocFile(String docfile) throws FileNotFoundException, IOException
    {
        // parsing nih...
        FileReader fr=new FileReader(docfile);
        BufferedReader br=new BufferedReader(fr);
        List<CISIDocs> docsarr=new ArrayList<CISIDocs>();
        String line;
        int index=-1;
        String words="";
        CISIDocs docs=new CISIDocs();
        int state=STATE_START;
        String title="";
        String author="";
        String publish="";
        CISIDocs.CISI_X x=new CISIDocs.CISI_X();
        String newline=System.getProperty("line.separator");
        while(br.ready())
        {
            line=br.readLine();
            if(line.length()>1)
            {
                if(line.substring(0, 2).equals(".I"))
                {
                    if(state!=STATE_START)
                    {
                        // add entry
                        docs=new CISIDocs(index, title, author, words, publish, x);
                        docsarr.add(docs);
                    }
                    state=PARSING_INDEX;
                    title="";
                    author="";
                    words="";
                    publish="";
                    x=new CISIDocs.CISI_X();
                }
                else if(line.substring(0, 2).equals(".W"))
                {
                    state=PARSING_WORDS;
                    line=br.readLine();
                }
                else if(line.substring(0, 2).equals(".T"))
                {
                    state=PARSING_TITLE;
                    line=br.readLine();
                }
                else if(line.substring(0, 2).equals(".A"))
                {
                    state=PARSING_AUTHOR;
                    line=br.readLine();
                }
                else if(line.substring(0, 2).equals(".X"))
                {
                    state=PARSING_X;
                    line=br.readLine();
                }
                switch(state)
                {
                    case PARSING_INDEX:
                        index=Integer.parseInt(line.substring(3),10);
                        break;
                    case PARSING_TITLE:
                        title+=line+newline;
                        break;
                    case PARSING_AUTHOR:
                        author+=line+newline;
                        break;
                    case PARSING_WORDS:
                        words+=line+newline;
                        break;
                    case PARSING_PUBLISH:
                        publish+=line+newline;
                        break;
                    case PARSING_X:
                        String[] arr=line.split("\t");
                        x.addRow(Integer.parseInt(arr[0], 10), Integer.parseInt(arr[1], 10),Integer.parseInt(arr[2], 10));
                        break;
                }
            }
        }
        docs=new CISIDocs(index, title, author, words, publish, x);
        docsarr.add(docs);
        return docsarr;
    }

    public List<CISIDocs> getDocs()
    {
        return docs;
    }

    public List<CISIQuery> getQueries()
    {
        return queries;
    }

    public List<CISIQRels> getRels()
    {
        return rels;
    }
    
    public CISIDocs getDocumentByID(int id)
    {
        return docs.get(id-1);
    }
    
    public CISIQuery getQueryByID(int id)
    {
        return queries.get(id-1);
    }
    
    public boolean isRelevant(int queryID, int documentID)
    {
        boolean relevant=false;
        for(int i=0;i<rels.size();i++)
        {
            CISIQRels rel=rels.get(i);
            if(rel.getQueryID()==queryID && rel.getDocumentID()==documentID)
            {
                relevant=true;
                break;
            }
        }
        return relevant;
    }
    
    public List<Integer> getRelevantDocumentIDs(int queryID)
    {
        List<Integer> docIDs=new ArrayList<Integer>();
        for(int i=0;i<rels.size();i++)
        {
            CISIQRels rel=rels.get(i);
            if(rel.getQueryID()==queryID)
            {
                docIDs.add(rel.getDocumentID());
            }
        }
        return docIDs;
    }
    
    public boolean isStopword(String word)
    {
        boolean exist=false;
        for(CISIStopword stop : stopwords)
        {
            if(stop.getStopword().equals(word))
            {
                exist=true;
                break;
            }
        }
        return exist;
    }
}